package vip.xiaonuo.biz.modular.event.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.BetweenFormatter;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vip.xiaonuo.biz.modular.apilog.entity.DevApiLog;
import vip.xiaonuo.biz.modular.apilog.mapper.DevApiLogMapper;
import vip.xiaonuo.biz.modular.cabinetdoor.mapper.BizCabinetDoorMapper;
import vip.xiaonuo.biz.modular.cabinetdoor.vo.BizCabinetDoorResp;
import vip.xiaonuo.biz.modular.event.entity.BizEvent;
import vip.xiaonuo.biz.modular.event.entity.BizEventConfig;
import vip.xiaonuo.biz.modular.event.mapper.BizEventConfigMapper;
import vip.xiaonuo.biz.modular.event.mapper.BizEventMapper;
import vip.xiaonuo.biz.modular.event.service.BizEventDoorService;
import vip.xiaonuo.biz.modular.event.service.BizEventReplaceService;
import vip.xiaonuo.biz.modular.event.util.EventActionUtil;
import vip.xiaonuo.common.util.AliyunSmsUtil;
import vip.xiaonuo.dev.api.DevConfigApi;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional
public class BizEventDoorServiceImpl implements BizEventDoorService {

    @Resource
    private BizEventConfigMapper bizEventConfigMapper;

    @Resource
    private BizEventMapper bizEventMapper;

    @Resource
    private BizEventReplaceService bizEventReplaceService;

    @Resource
    private DevApiLogMapper devApiLogMapper;

    @Resource
    private BizCabinetDoorMapper bizCabinetDoorMapper;

    @Override
    public void recordOpenDoor(DevApiLog apiLog) {
        //查询对应配置
        BizEventConfig eventConfig = bizEventConfigMapper.selectById("5");
        //事件描述
        String eventDesc = eventConfig.getEventDesc();
        //柜门名称
        String doorName = bizEventReplaceService.getCbaDoorNameForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
        BizCabinetDoorResp cabinetDoorResp = bizEventReplaceService.getCbaDoorRespForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
        eventDesc = eventDesc.replace("{{cab-door}}", doorName);
        //组合实体类
        BizEvent event = BeanUtil.toBean(eventConfig, BizEvent.class);
        event.setApiLogId(apiLog.getId());
        event.setEventConfigId(eventConfig.getId());
        event.setEventTime(apiLog.getEventTime());
        event.setEventDesc(eventDesc);
        event.setEventUserId(apiLog.getUserId());
        event.setEventAction(EventActionUtil.getEventAction(apiLog.getReqType()));
        event.setCabinetGroupId(cabinetDoorResp.getCabinetGroupId());
        event.setCabinetId(cabinetDoorResp.getCabinetInfoId());
        event.setCabinetDoorId(cabinetDoorResp.getId());
        event.setAdminId(apiLog.getAdminId());
        bizEventReplaceService.clearBizEvent(event);
        bizEventMapper.insert(event);

        if (StringUtils.isBlank(apiLog.getUserId())) {
            //无用户开门 记录非用户认证开门
            this.nonAuthOpenDoor(apiLog);
        }
        if (apiLog.getPariFlag() == 0) {
            if (cabinetDoorResp.getInitFlag() == 0) {
                //开关门事件不成对
                this.noClose(apiLog);
            } else {
                //更新初始化状态
                bizCabinetDoorMapper.updateInitFlagById(cabinetDoorResp.getId());
            }
        }
    }

    @Override
    public void recordCloseDoor(DevApiLog apiLog) {
        //查询对应配置
        BizEventConfig eventConfig = bizEventConfigMapper.selectById("6");
        //请求json
        JSONObject reqJson = JSON.parseObject(apiLog.getReqJson());
        //事件描述
        String eventDesc = eventConfig.getEventDesc();
        //柜门名称
        String doorName = bizEventReplaceService.getCbaDoorNameForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
        BizCabinetDoorResp cabinetDoorResp = bizEventReplaceService.getCbaDoorRespForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
        eventDesc = eventDesc.replace("{{cab-door}}", doorName);
        //组合实体类
        BizEvent event = BeanUtil.toBean(eventConfig, BizEvent.class);
        event.setApiLogId(apiLog.getId());
        event.setEventConfigId(eventConfig.getId());
        event.setEventTime(apiLog.getEventTime());
        event.setEventDesc(eventDesc);
        event.setEventUserId(apiLog.getUserId());
        event.setEventAction(EventActionUtil.getEventAction(apiLog.getReqType()));
        event.setCabinetGroupId(cabinetDoorResp.getCabinetGroupId());
        event.setCabinetId(cabinetDoorResp.getCabinetInfoId());
        event.setCabinetDoorId(cabinetDoorResp.getId());
        event.setAdminId(apiLog.getAdminId());
        bizEventReplaceService.clearBizEvent(event);
        bizEventMapper.insert(event);
        if (apiLog.getPariFlag() == 0) {
            if (cabinetDoorResp.getInitFlag() == 0) {
                //开关门事件不成对
                this.noOpen(apiLog);
            } else {
                //更新初始化状态
                bizCabinetDoorMapper.updateInitFlagById(cabinetDoorResp.getId());
            }
        }
    }

    @Override
    public void handleDoorNotClose() {
        DevConfigApi devConfigApi = SpringUtil.getBean(DevConfigApi.class);
        String limit_time = devConfigApi.getValueByKey("MAXIMUM_OPENING_TIME_LIMIT");
        List<DevApiLog> apiList = devApiLogMapper.getListForNotClose();
        for (DevApiLog item : apiList) {
            //判断是否生成过事件
            int eventCount = bizEventMapper.countByApiLogId(item.getId(),"SJ011");
            if(eventCount==0){
                //间隔时间-单位分钟
                long betweenMin = DateUtil.between(item.getEventTime(), DateUtil.date(), DateUnit.MINUTE,false);
                if(betweenMin>=Long.valueOf(limit_time)){
                    //生成超时未关门事件
                    this.noColseWarn(item);
                }
            }
        }
    }

    /**
     * 非用户认证开门
     */
    private void nonAuthOpenDoor(DevApiLog apiLog) {
        //查询对应配置
        BizEventConfig eventConfig = bizEventConfigMapper.selectById("12");
        //事件描述
        String eventDesc = eventConfig.getEventDesc();
        //柜门名称
        String doorName = bizEventReplaceService.getCbaDoorNameForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
        BizCabinetDoorResp cabinetDoorResp = bizEventReplaceService.getCbaDoorRespForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
        eventDesc = eventDesc.replace("{{cab-door}}", doorName);
        //组合实体类
        BizEvent event = BeanUtil.toBean(eventConfig, BizEvent.class);
        event.setApiLogId(apiLog.getId());
        event.setEventConfigId(eventConfig.getId());
        event.setEventTime(apiLog.getEventTime());
        event.setEventDesc(eventDesc);
        event.setEventUserId(apiLog.getUserId());
        event.setEventAction(EventActionUtil.getEventAction(apiLog.getReqType()));
        event.setCabinetGroupId(cabinetDoorResp.getCabinetGroupId());
        event.setCabinetId(cabinetDoorResp.getCabinetInfoId());
        event.setCabinetDoorId(cabinetDoorResp.getId());
        bizEventReplaceService.clearBizEvent(event);
        bizEventMapper.insert(event);

        //【邮件】柜门管理员
        bizEventReplaceService.sendEmailForDoorAdmin(event);
    }

    /**
     * 开关门不成对-开门用
     *
     * @param apiLog
     */
    private void noClose(DevApiLog apiLog) {
        //查询对应配置
        BizEventConfig eventConfig = bizEventConfigMapper.selectById("9");
        //事件描述
        String eventDesc = eventConfig.getEventDesc();
        //柜门名称
        String doorName = bizEventReplaceService.getCbaDoorNameForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
        BizCabinetDoorResp cabinetDoorResp = bizEventReplaceService.getCbaDoorRespForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
        eventDesc = eventDesc.replace("{{cab-door}}", doorName);
        //组合实体类
        BizEvent event = BeanUtil.toBean(eventConfig, BizEvent.class);
        event.setApiLogId(apiLog.getId());
        event.setEventConfigId(eventConfig.getId());
        event.setEventTime(apiLog.getEventTime());
        event.setEventDesc(eventDesc);
        event.setEventUserId(apiLog.getUserId());
        event.setEventAction(EventActionUtil.getEventAction(apiLog.getReqType()));
        event.setCabinetGroupId(cabinetDoorResp.getCabinetGroupId());
        event.setCabinetId(cabinetDoorResp.getCabinetInfoId());
        event.setCabinetDoorId(cabinetDoorResp.getId());
        bizEventReplaceService.clearBizEvent(event);
        bizEventMapper.insert(event);

        //【邮件】柜门管理员
        bizEventReplaceService.sendEmailForDoorAdmin(event);
    }

    /**
     * 开关门不成对-关门用
     *
     * @param apiLog
     */
    private void noOpen(DevApiLog apiLog) {
        //查询对应配置
        BizEventConfig eventConfig = bizEventConfigMapper.selectById("10");
        //事件描述
        String eventDesc = eventConfig.getEventDesc();
        //柜门名称
        String doorName = bizEventReplaceService.getCbaDoorNameForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
        BizCabinetDoorResp cabinetDoorResp = bizEventReplaceService.getCbaDoorRespForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
        eventDesc = eventDesc.replace("{{cab-door}}", doorName);
        //组合实体类
        BizEvent event = BeanUtil.toBean(eventConfig, BizEvent.class);
        event.setApiLogId(apiLog.getId());
        event.setEventConfigId(eventConfig.getId());
        event.setEventTime(apiLog.getEventTime());
        event.setEventDesc(eventDesc);
        event.setEventUserId(apiLog.getUserId());
        event.setEventAction(EventActionUtil.getEventAction(apiLog.getReqType()));
        event.setCabinetGroupId(cabinetDoorResp.getCabinetGroupId());
        event.setCabinetId(cabinetDoorResp.getCabinetInfoId());
        event.setCabinetDoorId(cabinetDoorResp.getId());
        bizEventReplaceService.clearBizEvent(event);
        bizEventMapper.insert(event);

        //【邮件】柜门管理员
        bizEventReplaceService.sendEmailForDoorAdmin(event);
    }

    /**
     * 超时未关门
     * @param apiLog
     */
    private void noColseWarn(DevApiLog apiLog){
        //查询对应配置
        BizEventConfig eventConfig = bizEventConfigMapper.selectById("11");
        //事件描述
        String eventDesc = eventConfig.getEventDesc();
        //柜门名称
        String doorName = bizEventReplaceService.getCbaDoorNameForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
        BizCabinetDoorResp cabinetDoorResp = bizEventReplaceService.getCbaDoorRespForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
        eventDesc = eventDesc.replace("{{cab-door}}", doorName);
        //超期时间
        String ovdStr = DateUtil.formatBetween(apiLog.getEventTime(), DateUtil.date(), BetweenFormatter.Level.SECOND);
        eventDesc = eventDesc.replace("{{out-time}}", ovdStr);
        //组合实体类
        BizEvent event = BeanUtil.toBean(eventConfig, BizEvent.class);
        event.setApiLogId(apiLog.getId());
        event.setEventConfigId(eventConfig.getId());
        event.setEventTime(DateUtil.date());
        event.setEventDesc(eventDesc);
        event.setEventUserId(apiLog.getUserId());
        event.setEventAction(EventActionUtil.getEventAction(apiLog.getReqType()));
        event.setCabinetGroupId(cabinetDoorResp.getCabinetGroupId());
        event.setCabinetId(cabinetDoorResp.getCabinetInfoId());
        event.setCabinetDoorId(cabinetDoorResp.getId());
        bizEventReplaceService.clearBizEvent(event);
        bizEventMapper.insert(event);

        //【邮件+短信】开门用户，柜门管理员
        bizEventReplaceService.sendEmailForUser(apiLog.getUserId(),event);
        bizEventReplaceService.sendEmailForDoorAdmin(event);
        Map<String, String> content = new HashMap<>();
        content.put("cabdoor", doorName);
        content.put("outtime", ovdStr);
        bizEventReplaceService.sendSmsForUser(apiLog.getUserId(),event, AliyunSmsUtil.CLOSE_DOOR_TIMEOUT, content);
        bizEventReplaceService.sendSmsForDoorAdmin(event, AliyunSmsUtil.CLOSE_DOOR_TIMEOUT, content);
    }
}
